import { DataObject } from 'json2md';
import parser from '../../parser/script';
import { formatArrayItemToMdValue, generateFlow, isNotEmptyObject } from '../../utils';

import { IScriptParseResult, IScriptParseResultMdConfig } from '../../types/script';

export default generateDoc;

/**
 * 输出文档
 */
function generateDoc(options: {
    input: string;
    output: string;
    parseResultPoint?: (parseResult: IScriptParseResult) => IScriptParseResult;
    formatContentConfigsPoint?: (configs: IScriptParseResultMdConfig) => IScriptParseResultMdConfig;
    markdownJsonPoint?: (configs: Array<DataObject>) => Array<DataObject>;
    markdownContentPoint?: (mdContent: string) => string;
    success?: () => void;
}) {
    try {
        const res = parser(options.input);
        if (res) {
            const { type } = res;

            generateFlow(res, {
                output: options.output,

                getFormatContentConfigs(parseResult) {
                    if (type === 'javascript') {
                        return buildJavascriptDoc(parseResult);
                    } else if (type === 'typescript') {
                        return buildTypescriptDoc(parseResult);
                    }
                    return {};
                },

                getMarkdownConfigs(configs) {
                    if (type === 'javascript') {
                        return generateJavascriptDoc(configs);
                    } else if (type === 'typescript') {
                        return generateTypescriptDoc(configs);
                    }
                    return [];
                },

                parseResultPoint: options.parseResultPoint,
                formatContentConfigsPoint: options.formatContentConfigsPoint,
                markdownJsonPoint: options.markdownJsonPoint,
                markdownContentPoint: options.markdownContentPoint,
                success: options.success
            });
        }
    } catch (error) {
        throw error;
    }
}

/**
 * 构建 Javascript 文档格式
 */
function buildJavascriptDoc(parseResult: IScriptParseResult) {
    const configs: IScriptParseResultMdConfig = {};
    const { functions } = parseResult;

    if (functions) {
        configs.functions = {};
        for (const name in functions) {
            const info = functions[name];
            if (isNotEmptyObject(info)) {
                configs.functions[name] = {};
                if (info.desp) {
                    configs.functions[name].desp = info.desp;
                }
                if (info.params?.length) {
                    configs.functions[name].params = info.params.map(param => {
                        return formatArrayItemToMdValue([param.name, param.type?.join(' \\| '), param.desp], { length: 3 }) as string[];
                    });
                }
                if (info.returns) {
                    configs.functions[name].returns = formatArrayItemToMdValue([info.returns.type?.join(' \\| '), info.returns.desp], { length: 2 }) as string[];
                }
            }
        }
    }

    return configs;
}

/**
 * 构造 Javascript 文档配置
 */
function generateJavascriptDoc(configs: IScriptParseResultMdConfig) {
    const rets: Array<DataObject> = [];
    const { functions } = configs;

    if (functions) {
        for (const name in functions) {
            const info = functions[name];

            rets.push({ h2: name });

            if (isNotEmptyObject(info)) {
                if (info.desp) {
                    rets.push({ blockquote: info.desp });
                }
                if (info.params?.length) {
                    rets.push({
                        table: { headers: ['参数', '类型', '说明'], rows: info.params }
                    });
                }
                if (info.returns) {
                    rets.push({
                        table: { headers: ['返回类型', '说明'], rows: [info.returns] }
                    });
                }
            }
        }
    }

    return rets;
}

/**
 * 构建 Tavascript 文档格式
 */
function buildTypescriptDoc(parseResult: IScriptParseResult) {
    const configs: IScriptParseResultMdConfig = {};
    return configs;
}

/**
 * 构造 Typescript 文档配置
 */
function generateTypescriptDoc(configs: IScriptParseResultMdConfig) {
    return [];
}
